﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gnosis.Alexandria.Model
{
    public abstract class NamedHashedBase
        : NamedBase, IHashed
    {
        private string _hash = string.Empty;

        private static Dictionary<string, string> hashWordsToNormalize = new Dictionary<string, string> { 
            {"!", ""}, {"@", ""}, {"#", ""}, {"$", ""}, {"%", ""}, {"^", ""}, {"&", ""}, {"*", ""}, {"(", ""}, {")", ""}, {"-", ""}, {"_", ""}, {"+", ""}, {"=", ""},
            {"{", ""}, {"}", ""}, {"[", ""}, {"]", ""}, {"|", ""}, {"\\", ""}, {":", ""}, {";", ""}, {"\"", ""}, {"'", ""}, {"<", ""}, {">", ""}, {",", ""}, {".", ""},
            {"?", ""}, {"/", ""}, {"~", ""}, {"`", ""}, 
            {"THE", ""}, {"A", ""}, {"OF", ""}, {"AT", ""}, {"AND", ""}, {"IN", ""}, {"WITH", ""}, {"BUT", ""}, {"OR", ""}, {"FOR", ""}, {"NOR", ""}, {"YET", ""},
            {"1", "ONE"}, {"2", "TWO"}, {"3", "THREE"}, {"4", "FOUR"}, {"5", "FIVE"}, {"6", "SIX"}, {"7", "SEVEN"}, {"8", "EIGHT"}, {"9", "NINE"}, {"10", "TEN"}
        };


        public static string GetHash(string name)
        {
            if (string.IsNullOrEmpty(name))
                return string.Empty;


            var result = new StringBuilder();
            var wordDelimiters = new string[] { " ", "\t", "\r\n", "\n"};
            var words = name.Split(wordDelimiters, StringSplitOptions.RemoveEmptyEntries);

            foreach (string word in words)
            {
                var key = word.Trim().ToUpper();
                if (hashWordsToNormalize.ContainsKey(key))
                    result.Append(hashWordsToNormalize[key]);
                else result.Append(key);
            }

            return result.ToString();
        }

        protected override void NameSet(string name)
        {
            _hash = GetHash(name);
        }

        protected override void InitializeField(string fieldName, object value)
        {
            if (fieldName == "Hash")
                _hash = (string)value ?? string.Empty;
            else base.InitializeField(fieldName, value);
        }

        #region IHashed Members

        public string Hash
        {
            get { return _hash; }
            set
            {
                if (_hash != value)
                {
                    _hash = value;
                    AddChange("Hash", value);
                }
            }
        }

        #endregion
    }
}
